package com.zb.automation.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.zb.automation.common.Constant;
import com.zb.automation.enums.ExcelPrefixEnum;
import com.zb.automation.model.request.ReqSwaggerDTO;
import com.zb.automation.model.response.AnalysisSwaggerDTO;
import com.zb.automation.model.response.JsonParamsDTO;
import com.zb.automation.service.AnalysisJsonService;
import com.zb.automation.service.impl.convertor.AnalysisJsonConvertor;
import com.zb.automation.service.impl.swagger.SwaggerAnalysis;
import com.zb.automation.util.LocalDateUtils;
import com.zb.automation.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.list.TreeList;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

@Slf4j
@Service
public class AnalysisJsonServiceImpl implements AnalysisJsonService {

    @Value("${excel.export.showCode:false}")
    private Boolean excelExportShowCode;

    @Value("${excel.export.showParamType:true}")
    private Boolean showParamType;

    private static final String ARRAY_CAPITALIZE = "Array";
    private static final String ARRAY_LOWERCASE = "array";

    private static final String ARRAY_INDEX = "[0]";

    private static final String UNKNOWN = "unknown";

    private List<List<String>> headerName = new ArrayList<>();

    @Override
    public List<JsonParamsDTO> analysisJson(String json) {
        List<JsonParamsDTO> list = new TreeList<>();
        AnalysisJsonConvertor.json2Param(list, json);
        return list;
    }

    @Override
    public List<AnalysisSwaggerDTO> analysisSwagger2Tree(String path) {
        return SwaggerAnalysis.analysisSwagger2Tree(path);
    }

    @Override
    public List<ReqSwaggerDTO> analysisSwagger2List(String path) {
        return SwaggerAnalysis.analysisSwagger2List(path);
    }


    @Override
    public String exportExcel(List<ReqSwaggerDTO> reqSwaggerDTOS) {
        String fileName = LocalDateUtils.nowString() + StringUtils.getRandomFixLen(5) + Constant.POINT + ExcelPrefixEnum.XLSX;
        String staticPath = "";
        try {
            staticPath = ResourceUtils.getURL(Constant.CLASS_PATH).getPath() + Constant.STATIC_PATH;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        String finalStaticPath = staticPath;
        ExcelWriter excelWriter = EasyExcel.write(finalStaticPath + Constant.SLASH + fileName).build();
        reqSwaggerDTOS.stream().filter(x-> x.getParentId() != 0).forEach(x->{
            List<List<String>> header = new ArrayList<>();
            x.getReqParamt().stream().forEach(y->{
                String paramDesc = y.getParamDesc();
                String paramName = Constant.$ + Constant.POINT + y.getParamName();
                if(CollectionUtils.isEmpty(y.getChildren())){
                    List<String> cells = new ArrayList<>();
                    cells.add(paramDesc + Constant.LINE_FEED + (showParamType?StringUtils.bracketsPackage(y.getParamType(),UNKNOWN):Constant.EMPTY_STRING));
                    if(excelExportShowCode){
                        cells.add(paramName);
                    }
                    header.add(cells);
                    return;
                }
                if(excelExportShowCode){
                    if(ARRAY_CAPITALIZE.equals(y.getParamType()) || ARRAY_LOWERCASE.equals(y.getParamType())){
                        paramName = paramName + ARRAY_INDEX;
                    }
                }
                child(paramName,paramDesc,y.getChildren());
                header.addAll(headerName);

            });
            HorizontalCellStyleStrategy horizontalCellStyleStrategy = AnalysisJsonConvertor.buildHorizontalCellStyleStrategy();
            WriteSheet writeSheet = EasyExcel.writerSheet(reqSwaggerDTOS.indexOf(x),Pattern.compile(Constant.SPECIAL_SYMBOL_REG_EX).matcher(x.getPathName()).replaceAll("-"))
                    .registerWriteHandler(horizontalCellStyleStrategy)
                    .registerWriteHandler(new SimpleColumnWidthStyleStrategy(10))
                    .head(header)
                    .needHead(Boolean.TRUE)
                    .build();
            excelWriter.write(new ArrayList<>(), writeSheet);
         });
        excelWriter.finish();
        return fileName;
    }

    private void child(String paramName,String paramDesc,List<JsonParamsDTO> jsonParamsDTOS){
        if(CollectionUtils.isEmpty(jsonParamsDTOS)){
            return;
        }
        jsonParamsDTOS.stream().forEach(x->{
            ArrayList<String> cells = new ArrayList<>();
            cells.add(paramDesc + Constant.LINE_FEED + Constant.LOT + Constant.LINE_FEED + x.getParamDesc() + Constant.LINE_FEED +
                    (showParamType?StringUtils.bracketsPackage(x.getParamType(),UNKNOWN):Constant.EMPTY_STRING));
            if(excelExportShowCode){
                cells.add(paramName + Constant.POINT + x.getParamName());
            }
            headerName.add(cells);
            List<JsonParamsDTO> children = x.getChildren();
            if(CollectionUtils.isEmpty(children)){
                return;
            }
            child(paramName + Constant.POINT+x.getParamName(),paramDesc + Constant.LINE_FEED+Constant.LOT + Constant.LINE_FEED + x.getParamDesc(),children);
        });
    }

}
